package cn.abcsys.cloud.devops.runtime.service.impl;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import cn.abcsys.cloud.devops.runtime.bean.GridBean;
import cn.abcsys.cloud.devops.runtime.bean.Result;
import cn.abcsys.cloud.devops.runtime.common.Constant;
import cn.abcsys.cloud.devops.runtime.common.Status;
import cn.abcsys.cloud.devops.runtime.core.HostCore;
import cn.abcsys.cloud.devops.runtime.dao.HostMapper;
import cn.abcsys.cloud.devops.runtime.dao.RegistryMapper;
import cn.abcsys.cloud.devops.runtime.entity.Host;
import cn.abcsys.cloud.devops.runtime.entity.Registry;
import cn.abcsys.cloud.devops.runtime.model.RegistryModel;
import cn.abcsys.cloud.devops.runtime.service.RegistryService;
/**
 * 仓库管理业务处理
 * @author mayunhao
 *
 */
@Component
public class RegistryServiceImpl implements RegistryService {
	private static final Logger LOGGER = Logger.getLogger(RegistryServiceImpl.class);
	@Autowired
	private RegistryMapper registryMapper;
	@Autowired
	private HostMapper hostMapper;
	@Autowired
	private HostCore hostCore;
	@Override
	public GridBean getRegistryList(RegistryModel registryModel) {
		int page = registryModel.getPage();
		int rows = registryModel.getRows();
		int totalpage = 0;
		Long totalNum = 0l;
		Page<Registry> pageObject = new Page<Registry>();
		try {
			Registry registry = new Registry();
			registry.setRegistryName(registryModel.getRegistryName());
			registry.setRegistryStatus((byte)Status.COMMON.NORMAL.ordinal());
			PageHelper.startPage(page, rows);
			registry.setRegistryStatus((byte)Status.COMMON.NORMAL.ordinal());
			List<Registry> List = registryMapper.selectRegistryList(registry);
			for(Registry temp: List){
				if(temp.getHaEnable()==Status.JUDGE.NO.ordinal()){
					String hostIp = temp.getHostId().split(Constant.separator)[0];
					Host host = hostMapper.getHostDetail(Integer.parseInt(hostIp));
					temp.setServiceIp(host.getHostIp());
				}
				pageObject.add(temp);
			}
			totalpage = ((Page<?>) List).getPages();
			totalNum = ((Page<?>) List).getTotal();
		} catch (SQLException e) {
			LOGGER.error("批量查询仓库失败:"+e.getMessage());
		}
		GridBean gridBean = new GridBean(page, totalpage, totalNum.intValue(), pageObject);
		return gridBean;
	}

	@Override
	public Result getRegistryDetail(Integer registryId) {
		Result result = null;
		try {
			Registry registry = registryMapper.getRegistryDetail(registryId);
			if(null!=registry){
				result = new Result(true,JSONObject.toJSON(registry),"success");
			}else{
				result = new Result(false,"未查到相关结果");
			}
		} catch (SQLException e) {
			LOGGER.error("查询仓库详情失败:"+e.getMessage());
			result = new Result(false, "查询失败："+e.getMessage());
		}
		return result;
	}

	@Override
	public Result createRegistry(Registry registry) {
		Result result = new Result(true, "创建仓库成功");
		try {
			String idstr = registry.getHostId();
			if(StringUtils.isEmpty(idstr)){
				return new Result(false, "请添加仓库主机");
			}
			String[] ids = idstr.split(Constant.separator);
			if(ids.length==0){
				return new Result(false, "请添加仓库主机");
			}
			if(registry.getHaEnable()==Status.JUDGE.YES.ordinal()
					&&ids.length<=1){
				return new Result(false, "请添加仓库高可用主机");
			}
			if(registry.getHaEnable()==Status.JUDGE.YES.ordinal()
					&&StringUtils.isEmpty(registry.getServiceIp())){
				return new Result(false, "请添加仓库高可用IP地址");
			}
			//判断仓库主机的进程是否已经启动，如果启动，认为是在其他仓库服务中，不允许使用这个主机创建信息的仓库
			for(int i=0;i<ids.length;i++){
				String registryHostId = ids[i];
				if(StringUtils.isEmpty(registryHostId)){
					continue;
				}
				//step2-1:检查registry主机是否已经启动
				result = this.isRunning(Integer.valueOf(registryHostId));
				if(result.isSuccess()){
					return new Result(false,result.getMessage());
				}
			}
			//对外提供服务的地址
			String service_ip = registry.getServiceIp();
			List<Host> updateList = new ArrayList<>();
			//step1:判断是否高可用
			if(registry.getHaEnable()==Status.JUDGE.YES.ordinal()){
				for(int i=0;i<ids.length;i++){
					Host registryHost = null;
					String registryHostId = ids[i];
					if(StringUtils.isEmpty(registryHostId)){
						continue;
					}
					try {
						registryHost = hostMapper.getHostDetail(Integer.valueOf(registryHostId));
						updateList.add(registryHost);
					} catch (NumberFormatException e) {
						return new Result(false, "主机ID["+registryHostId+"]转换异常:"+e.getMessage());
					} catch (SQLException e) {
						return new Result(false, "主机ID["+registryHostId+"]查询异常:"+e.getMessage());
					}
					if(null==registryHost){
						return new Result(false, "主机ID["+registryHostId+"]不存在");
					}
					Map<String, String> params = new HashMap<>();
					params.put(""+(i+1), registry.getServiceIp());
					//step2-2:高可用设置服务地址为虚拟IP地址
					result = hostCore.startDistribution(registryHost.getHostIp(), params);
					if(!result.isSuccess()){
						return result;
					}
				}
			}else{
				Host registryHost = null;
				String registryHostId = ids[0];
				try {
					registryHost = hostMapper.getHostDetail(Integer.valueOf(registryHostId));
				} catch (NumberFormatException e) {
					return new Result(false, "主机ID["+registryHostId+"]转换异常:"+e.getMessage());
				} catch (SQLException e) {
					return new Result(false, "主机ID["+registryHostId+"]查询异常:"+e.getMessage());
				}
				if(null==registryHost){
					return new Result(false, "主机ID["+registryHostId+"]不存在");
				}
				//虚拟地址设置为仓库主机地址
				service_ip = registryHost.getHostIp();
				registry.setServiceIp(service_ip);
				//step2-1:检查registry主机是否已经启动
				result = hostCore.isRunning(registryHost.getHostIp());
				if(result.isSuccess()){
					return new Result(false, "镜像仓库程序在运行状态，可能已被其他占用，请确认后停止仓库程序再执行此操作");
				}
				//step2-2:高可用设置服务地址为仓库主机地址
				result = hostCore.startDistribution(registryHost.getHostIp(), null);
				if(!result.isSuccess()){
					return result;
				}
			}
			registry.setRegistryStatus((byte)Status.COMMON.NORMAL.ordinal());
			int issuccess = registryMapper.insertRegistry(registry);
			if(issuccess!=1){
				return new Result(false, "创建仓库失败,原因未知");
			}
			for(Host host:updateList){
				host.setRegistryId(registry.getRegistryId());
				hostMapper.updateHost(host);
			}
		} catch (SQLException e) {
			LOGGER.error("创建仓库失败:"+e.getMessage());
			result = new Result(false, "创建仓库失败："+e.getMessage());
		}
		return result;
	}

	@Override
	public Result updateRegistry(Registry registry) {
		Result result = new Result(true, "更新仓库成功");
		try {
			Registry updateReg = registryMapper.getRegistryDetail(registry.getRegistryId());
			updateReg.setRegistryName(registry.getRegistryName());
			updateReg.setRegistryDesc(registry.getRegistryDesc());
			int issuccess = registryMapper.updateRegistry(updateReg);
			if(issuccess!=1){
				result = new Result(false, "更新仓库失败,原因未知");
			}
		} catch (SQLException e) {
			LOGGER.error("更新仓库失败:"+e.getMessage());
			result = new Result(false, "更新仓库失败："+e.getMessage());
		}
		return result;
	}

	@Override
	public Result deleteRegistry(Integer registryId) {
		Result result = new Result(true, "移除仓库成功");
		try {
			Registry registry = registryMapper.getRegistryDetail(registryId);
			if(null==registry){
				return new Result(false, "仓库主["+registryId+"]不存在");
			}
			String[] ids = registry.getHostId().split(Constant.separator);
			//step1:判断是否高可用
			if(registry.getHaEnable()==Status.JUDGE.YES.ordinal()){
				for(int i=0;i<ids.length;i++){
					Host registryHost = null;
					String registryHostId = ids[i];
					try {
						registryHost = hostMapper.getHostDetail(Integer.valueOf(registryHostId));
					} catch (NumberFormatException e) {
						return new Result(false, "主机ID["+registryHostId+"]转换异常:"+e.getMessage());
					} catch (SQLException e) {
						return new Result(false, "主机ID["+registryHostId+"]查询异常:"+e.getMessage());
					}
					if(null==registryHost){
						return new Result(false, "主机ID["+registryHostId+"]不存在");
					}
					//step2-1:检查registry仓库进程是否启动
					result = hostCore.isRunning(registryHost.getHostIp());
					if(result.isSuccess()){
						//step2-2:高可用停止distribution daemin
						result = hostCore.stopDistribution(registryHost.getHostIp());
						if(!result.isSuccess()){
							return result;
						}
					}
					//仓库主机registryid清空
					registryHost.setRegistryId(null);
					int re = hostMapper.updateHost(registryHost);
					if(re!=1){
						return new Result(false, "仓库主机状态更新失败");
					}
				}
			}else{
				Host registryHost = null;
				String registryHostId = ids[0];
				try {
					registryHost = hostMapper.getHostDetail(Integer.valueOf(registryHostId));
				} catch (NumberFormatException e) {
					return new Result(false, "主机ID["+registryHostId+"]转换异常:"+e.getMessage());
				} catch (SQLException e) {
					return new Result(false, "主机ID["+registryHostId+"]查询异常:"+e.getMessage());
				}
				if(null==registryHost){
					return new Result(false, "主机ID["+registryHostId+"]不存在");
				}
				//step2-1:检查registry仓库进程是否启动
				result = hostCore.isRunning(registryHost.getHostIp());
				if(result.isSuccess()){
					//停止仓库进程
					result = hostCore.stopDistribution(registryHost.getHostIp());
					if(!result.isSuccess()){
						return result;
					}
				}
				//仓库主机registryid清空
				registryHost.setRegistryId(null);
				int i = hostMapper.updateHost(registryHost);
				if(i!=1){
					return new Result(false, "仓库主机状态更新失败");
				}
			}
			int issuccess = registryMapper.deleteRegistry(registryId);
			if(issuccess!=1){
				result = new Result(false, "移除仓库失败,原因未知");
			}
		} catch (SQLException e) {
			LOGGER.error("移除仓库失败:"+e.getMessage());
			result = new Result(false, "移除仓库失败："+e.getMessage());
		}
		return result;
	}

	@Override
	public Result listAll() {
		try {
			Registry registry = new Registry();
			registry.setRegistryStatus((byte)Status.COMMON.NORMAL.ordinal());
			List<Registry> registries = registryMapper.selectRegistryList(registry);
			return new Result(true, registries, "success");
		} catch (SQLException e) {
			return new Result(false, "查询仓库异常："+e.getMessage());
		}
		
	}
	/**
	 * mayunhao
	* @Title: isRunning 
	* @Description: 检查仓库进程是否启动
	* @param @param hostIds
	* @param @param cluster
	* @param @param userId
	* @param @return    设定文件 
	* @return Result    返回类型 
	* @throws
	 */
	private Result isRunning(Integer registryHostId) {
		if(null==registryHostId){
			return new Result(false, "请选择添加主机");
		}
		Host registryHost = null;
		try {
			registryHost = hostMapper.getHostDetail(Integer.valueOf(registryHostId));
		} catch (NumberFormatException e) {
			return new Result(false, "主机ID["+registryHostId+"]转换异常:"+e.getMessage());
		} catch (SQLException e) {
			return new Result(false, "主机ID["+registryHostId+"]查询异常:"+e.getMessage());
		}
		if(null==registryHost){
			return new Result(false, "主机ID["+registryHostId+"]不存在");
		}
		//检查主机kubernetes进程是否已经启动
		Result result = hostCore.isRunning(registryHost.getHostIp());
		if(result.isSuccess()){
			return new Result(true, "主机["+registryHost.getHostIp()+"]镜像仓库程序在运行状态，可能已被其他占用，请确认后停止仓库程序再执行此操作");
		}
		return new Result(true);
	}
}
